//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "PearsonCorrelation.h"

#include <math.h>

#include <iostream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PearsonCorrelation::PearsonCorrelation(): xMean(0),
                                          yMean(0),
                                          coefficient(0) {

  this->x           = new TListE <double> ();
  this->y           = new TListE <double> ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PearsonCorrelation::PearsonCorrelation(const PearsonCorrelation& pearsonCorrelation): xMean(pearsonCorrelation.xMean),
                                                                                      yMean(pearsonCorrelation.yMean),
                                                                                      coefficient(pearsonCorrelation.coefficient) {

  this->x           = new TListE <double> (pearsonCorrelation.x);
  this->y           = new TListE <double> (pearsonCorrelation.y);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PearsonCorrelation::PearsonCorrelation(const PearsonCorrelation* pearsonCorrelation): xMean(pearsonCorrelation->xMean),
                                                                                      yMean(pearsonCorrelation->yMean),
                                                                                      coefficient(pearsonCorrelation->coefficient) {

  this->x           = new TListE <double> (pearsonCorrelation->x);
  this->y           = new TListE <double> (pearsonCorrelation->y);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PearsonCorrelation::~PearsonCorrelation() {
  
  if (this->x) delete this->x;
  if (this->y) delete this->y;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PearsonCorrelation::X(TListE <double>* x) {
  
  if (x) *(this->x) = *x;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PearsonCorrelation::Y(TListE <double>* y) {
  
  if (y) *(this->y) = *y;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PearsonCorrelation::XMean(double xMean) {
  
  this->xMean = xMean;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PearsonCorrelation::YMean(double yMean) {
  
  this->yMean = yMean;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PearsonCorrelation::Coefficient(double coefficient) {
  
  this->coefficient = coefficient;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <double>* PearsonCorrelation::X(void) {
  
  return this->x;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <double>* PearsonCorrelation::Y(void) {
  
  return this->y;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double PearsonCorrelation::XMean(void) {
  
  return this->xMean;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double PearsonCorrelation::YMean(void) {
  
  return this->yMean;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
double PearsonCorrelation::Coefficient(void) {
  
  return this->coefficient;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PearsonCorrelation::ComputeXMean(void) {

  return (this->ComputeMeanData(this->x, this->xMean))?true:false;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PearsonCorrelation::ComputeYMean(void) {

  return (this->ComputeMeanData(this->y, this->yMean))?true:false;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PearsonCorrelation::ComputeMeanData(TListE<double>* data, double& mean) {
  
  if (!data || !data->Length()) return false;
  
  mean = 0;
  
  data->SetInitial();
  while (data->SetNext())
    mean += *(data->GetCurrent());
  
  mean /= (double)data->Length(); 
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PearsonCorrelation::ComputeCoefficient(void) {

  if (!this->x || !this->x->Length() || !this->y || !this->y->Length())
    return false;
  
  if (!this->ComputeXMean()) return false;
  if (!this->ComputeYMean()) return false;
  
  double covXY = 0, desvX = 0, desvY = 0;
  
  for (long i = 0; i < this->x->Length() && i < this->y->Length(); i++) {
    
    if (!this->x->Get(i) || !this->x->Get(i)) return false;
    
    double xValue = *(this->x->Get(i));
    double yValue = *(this->y->Get(i));
    
    covXY += ((xValue - this->xMean) * (yValue - this->yMean));
    desvX += ((xValue - this->xMean) * (xValue - this->xMean));
    desvY += ((yValue - this->yMean) * (yValue - this->yMean));
    
  }
  
  this->coefficient = covXY / sqrt(desvX * desvY);
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//

